home *** CD-ROM | disk | FTP | other *** search
- /* cfengine for GNU
-
- Copyright (C) 1995
- Free Software Foundation, Inc.
-
- This file is part of GNU cfengine - written and maintained
- by Mark Burgess, Dept of Computing and Engineering, Oslo College,
- Dept. of Theoretical physics, University of Oslo
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
- */
-
-
- /*********************************************************************/
- /* */
- /* TOOLKITS: "object" library */
- /* */
- /*********************************************************************/
-
- #define INET
-
- #include "cf.defs.h"
- #include "cf.extern.h"
- #include "../pub/global.h"
- #include "../pub/md5.h"
-
- #ifdef HAVE_DB_2_H
- # include <db_2.h>
- #else
- # if defined HAVE_DB_H && defined HAVE_DB_185_H
- # include <db.h>
- # endif
- #endif
-
- #if HAVE_DB_DB_H
- # include <db/db.h>
- #endif
-
- /*******************************************************************/
-
- GetNameInfo()
-
- { int i, sz, found = false;
- char *sp,*sp2;
- time_t tloc;
- struct hostent *hp;
- struct sockaddr_in cin;
- #ifdef AIX
- char real_version[_SYS_NMLN];
- #endif
-
- VFQNAME[0] = VUQNAME[0] = '\0';
-
- if (uname(&VSYSNAME) == -1)
- {
- perror("uname ");
- FatalError("Uname couldn't get kernel name info!!\n");
- }
-
- #ifdef AIX
- snprintf(real_version, _SYS_NMLN, "%s.%s", VSYSNAME.version, VSYSNAME.release);
- strncpy(VSYSNAME.release, real_version, _SYS_NMLN);
- #endif
-
- for (sp = VSYSNAME.sysname; *sp != '\0'; sp++)
- {
- *sp = ToLower(*sp);
- }
-
- for (sp = VSYSNAME.machine; *sp != '\0'; sp++)
- {
- *sp = ToLower(*sp);
- }
-
-
- for (i = 0; CLASSATTRIBUTES[i][0] != '\0'; i++)
- {
- if (WildMatch(CLASSATTRIBUTES[i][0],VSYSNAME.sysname))
- {
- if (WildMatch(CLASSATTRIBUTES[i][1],VSYSNAME.machine))
- {
- if (WildMatch(CLASSATTRIBUTES[i][2],VSYSNAME.release))
- {
- if (UNDERSCORE_CLASSES)
- {
- sprintf(VBUFF,"_%s",CLASSTEXT[i]);
- AddClassToHeap(VBUFF);
- }
- else
- {
- AddClassToHeap(CLASSTEXT[i]);
- }
- found = true;
- break;
- }
- }
- else
- {
- Debug2("Cfengine: I recognize %s but not %s\n",VSYSNAME.sysname,VSYSNAME.machine);
- continue;
- }
- }
- }
-
- if ((sp = malloc(strlen(VSYSNAME.nodename)+1)) == NULL)
- {
- FatalError("malloc failure in initialize()");
- }
-
- strcpy(sp,VSYSNAME.nodename);
- SetDomainName(sp);
-
- strcpy(VPREFIX,VSYSNAME.nodename);
-
- for (sp2=sp; *sp2 != '\0'; sp2++) /* Truncate fully qualified name */
- {
- if (*sp2 == '.')
- {
- *sp2 = '\0';
- Debug("Truncating fully qualified hostname %s to %s\n",VSYSNAME.nodename,sp);
- break;
- }
- }
-
-
- VDEFAULTBINSERVER.name = sp;
-
- AddClassToHeap(CanonifyName(sp));
-
- VSYSTEMHARDCLASS = (enum classes) i;
-
-
- if ((tloc = time((time_t *)NULL)) == -1)
- {
- printf("Couldn't read system clock\n");
- }
-
-
- CFSTARTTIME = tloc;
-
- sprintf(VBUFF,"%s",ctime(&tloc));
- AddTimeClass(VBUFF);
-
-
- if (VERBOSE)
- {
- if (UNDERSCORE_CLASSES)
- {
- sprintf(VBUFF,"_%s",CLASSTEXT[i]);
- }
- else
- {
- sprintf(VBUFF,"%s",CLASSTEXT[i]);
- }
-
- if (ISCFENGINE)
- {
- printf ("GNU Configuration Engine - \n%s\n%s\n\n",VERSION,COPYRIGHT);
- }
- else
- {
- printf ("GNU Cfengine server daemon - \n%s\n%s\n\n",VERSION,COPYRIGHT);
- }
-
- printf ("------------------------------------------------------------------------\n\n");
- printf ("Host name is: %s\n",VSYSNAME.nodename);
- printf ("Operating System Type is %s\n",VSYSNAME.sysname);
- printf ("Operating System Release is %s\n",VSYSNAME.release);
- printf ("Architecture = %s\n\n\n",VSYSNAME.machine);
- printf ("Using internal soft-class %s for host %s\n\n",VBUFF,VSYSNAME.nodename);
- printf ("The time is now %s\n\n",ctime(&tloc));
- printf ("------------------------------------------------------------------------\n\n");
-
- }
-
- sprintf(VBUFF,"%d_bit",sizeof(long)*8);
- AddClassToHeap(VBUFF);
- Verbose("Additional hard class defined as: %s\n",VBUFF);
-
- sprintf(VBUFF,"%s_%s",VSYSNAME.sysname,VSYSNAME.release);
- AddClassToHeap(CanonifyName(VBUFF));
-
- Verbose("Additional hard class defined as: %s\n",VBUFF);
-
- sprintf(VBUFF,"%s_%s",VSYSNAME.sysname,VSYSNAME.machine);
- AddClassToHeap(CanonifyName(VBUFF));
-
- Verbose("Additional hard class defined as: %s\n",VBUFF);
-
- sprintf(VBUFF,"%s_%s_%s",VSYSNAME.sysname,VSYSNAME.machine,VSYSNAME.release);
- AddClassToHeap(CanonifyName(VBUFF));
-
- Verbose("Additional hard class defined as: %s\n",VBUFF);
-
- #ifdef HAVE_SYSINFO
- #ifdef SI_ARCHITECTURE
- sz = sysinfo(SI_ARCHITECTURE,VBUFF,bufsize);
- if (sz == -1)
- {
- Verbose("cfengine internal: sysinfo returned -1\n");
- }
- else
- {
- AddClassToHeap(CanonifyName(VBUFF));
- Verbose("Additional hard class defined as: %s\n",VBUFF);
- }
- #endif
- #endif
-
- sprintf(VBUFF,"%s_%s_%s_%s",VSYSNAME.sysname,VSYSNAME.machine,VSYSNAME.release,VSYSNAME.version);
-
- if (strlen(VBUFF) < maxvarsize-2)
- {
- strcpy(VARCH,CanonifyName(VBUFF));
- }
- else
- {
- Verbose("cfengine internal: $(arch) overflows maxvarsize! Truncating\n");
- strcpy(VARCH,CanonifyName(VSYSNAME.sysname));
- }
-
- AddClassToHeap(VARCH);
-
- Verbose("Additional hard class defined as: %s\n",VARCH);
-
- if (! found)
- {
- CfLog(cferror,"Cfengine: I don't understand what architecture this is!","");
- }
-
- strcpy(VBUFF,AUTOCONF_SYSNAME);
-
- AddClassToHeap(CanonifyName(VBUFF));
-
- Verbose("\nGNU autoconf class from compile time: %s\n\n",VBUFF);
- Verbose(" Careful with this - it might not be correct at run time if you have\n");
- Verbose(" several OS versions with binary compatibilty!\n\n");
-
- /* Get IP address from nameserver */
-
- if ((hp = gethostbyname(VSYSNAME.nodename)) == NULL)
- {
- return;
- }
- else
- {
- bzero(&cin,sizeof(cin));
- cin.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
- Verbose("Address given by nameserver: %s\n",inet_ntoa(cin.sin_addr));
- strcpy(VIPADDRESS,inet_ntoa(cin.sin_addr));
- for (sp = VIPADDRESS+strlen(VIPADDRESS)-1; *sp != '.'; sp--)
- {
- }
- *sp = '\0';
- AddClassToHeap(CanonifyName(VIPADDRESS));
-
- strcpy(VIPADDRESS,inet_ntoa(cin.sin_addr));
- AddClassToHeap(CanonifyName(VIPADDRESS));
- }
- }
-
- /*********************************************************************/
- /* TOOLKIT : files/directories */
- /**********************************************************************/
-
- TruncateFile(name)
-
- char *name;
-
- { struct stat statbuf;
- int fd;
-
- if (stat(name,&statbuf) == -1)
- {
- Debug2("cfengine: didn't find %s to truncate\n",name);
- return;
- }
- else
- {
- if ((fd = creat(name,000)) == -1) /* dummy mode ignored */
- {
- sprintf(OUTPUT,"creat(%s) failed\n",name);
- CfLog(cferror,OUTPUT,"creat");
- }
- else
- {
- close(fd);
- }
- }
- }
-
- /*************************************************************************/
-
- FileSecure (name)
-
- char *name;
-
- { struct stat statbuf;
-
- if (PARSEONLY || !CFPARANOID)
- {
- return true;
- }
-
- if (stat(name,&statbuf) == -1)
- {
- return false;
- }
-
- if (statbuf.st_uid != getuid())
- {
- sprintf(OUTPUT,"File %s is not owned by uid %d (security exception)",name,getuid());
- CfLog(cferror,OUTPUT,"");
- }
-
- /* Is the file writable by ANYONE except the owner ? */
-
- if (statbuf.st_mode & (S_IWGRP | S_IWOTH))
- {
- sprintf(OUTPUT,"File %s is writable by others (security exception)",name,getuid());
- CfLog(cferror,OUTPUT,"");
- return false;
- }
-
- return true;
- }
- /***************************************************************/
-
- ChecksumChanged(filename,digest,warnlevel,refresh)
-
- /* Returns false if filename never seen before, and adds a checksum
- to the database. Returns true if checksums do not match and also
- updates database to the new value */
-
- char *filename;
- char digest[17];
- int warnlevel,refresh;
-
- {
- #if defined HAVE_LIBDB && (defined HAVE_DB_H || defined HAVE_DB_DB_H) && defined HAVE_DB_185_H
- struct stat stat1, stat2;
- int i, matched, needupdate = false;
- DBT key,value;
- DB *dbp;
- DBC *dbcp;
- db_recno_t recno;
- char dbvalue[17],dbdigest[17];
- time_t tloc;
-
- Debug("ChecksumChanged: key %s in %s with data %s\n",filename,CHECKSUMDB,cfMDPrint(digest));
-
- if (CHECKSUMDB[0] == '\0')
- {
- if (ISCFENGINE)
- {
- CfLog(cferror,"(cfd) No database defined","");
- return false;
- }
- else
- {
- Debug("Direct comparison (no db)\n");
- cfMDFile(filename,dbdigest);
- for (i = 0; i < 16; i++)
- {
- if (digest[i] != dbdigest[i])
- {
- return true;
- }
- }
- return false;
- }
- }
-
- if (refresh)
- {
- /* Check whether database is current wrt local file */
-
- if (stat(filename,&stat1) == -1)
- {
- sprintf(OUTPUT,"Couldn't stat %s\n",filename);
- CfLog(cferror,OUTPUT,"stat");
- return false;
- }
-
- if (stat(CHECKSUMDB,&stat2) != -1)
- {
- if (stat1.st_mtime > stat2.st_mtime)
- {
- Debug("Checksum database is older than %s...refresh needed\n",filename);
- needupdate = true;
- }
- else
- {
- Debug("Checksum up to date..\n");
- }
- }
- else
- {
- needupdate = true;
- }
- }
-
- /* Open the database. */
-
- if ((errno = db_open(CHECKSUMDB,DB_BTREE, DB_CREATE, 0664, NULL, NULL, &dbp)) != 0)
- {
- sprintf(OUTPUT,"cfd: couldn't open checksum database %s\n",CHECKSUMDB);
- CfLog(cferror,OUTPUT,"db_open");
- Debug("Ended 2\n");
- return false;
- }
-
- Debug("Opening database file %s\n",CHECKSUMDB);
- bzero(&value,sizeof(value));
- bzero(&key,sizeof(key));
-
- key.data = filename;
- key.size = strlen(filename)+1;
- value.data = dbvalue;
- value.size = 17;
-
- if (needupdate)
- {
- cfMDFile(filename,dbdigest);
- dbdigest[16] = '\0';
-
- key.data = filename;
- key.size = strlen(filename)+1;
- value.data = (void *) dbdigest;
- value.size = 17;
-
- Debug("cfd: updating checksum for %s to %s\n",filename,cfMDPrint(value.data));
-
- if ((errno = dbp->del(dbp,NULL,&key,0)) != 0)
- {
- CfLog(cferror,"","db_store");
- }
-
- key.data = filename;
- key.size = strlen(filename)+1;
-
- if ((errno = dbp->put(dbp,NULL,&key,&value,0)) != 0)
- {
- CfLog(cferror,"put failed","db->put");
- }
- }
-
- if ((errno = dbp->get(dbp,NULL,&key,&value,0)) == 0)
- {
- /* The filename key was found in the db */
- Debug("Comparing %s (sent) with %s (db)\n",cfMDPrint(digest),cfMDPrint(value.data));
- bcopy(value.data,dbdigest,17);
-
- for (i = 0; i < 16; i++)
- {
- if (digest[i] != dbdigest[i])
- {
- Debug("cfd: Found checksum for %s in database but it didn't match\n",filename);
-
- CfLog(warnlevel,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!","");
- sprintf(OUTPUT,"SECURITY ALERT: Checksum for %s changed!",filename);
- CfLog(warnlevel,OUTPUT,"");
- CfLog(warnlevel,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!","");
-
- if (CHECKSUMUPDATES)
- {
- cfMDFile(filename,dbdigest);
- dbdigest[16] = '\0';
-
- key.data = filename;
- key.size = strlen(filename)+1;
- value.data = (void *) dbdigest;
- value.size = 17;
-
- Debug("cfd: updating checksum for %s to %s\n",filename,cfMDPrint(value.data));
-
- if ((errno = dbp->del(dbp,NULL,&key,0)) != 0)
- {
- CfLog(cferror,"","db_store");
- }
-
- key.data = filename;
- key.size = strlen(filename)+1;
-
- if ((errno = dbp->put(dbp,NULL,&key,&value,0)) != 0)
- {
- CfLog(cferror,"put failed","db->put");
- }
- }
-
- dbp->close(dbp,0);
- return true; /* Checksum updated but was changed */
- }
- }
-
- Debug("cfd: Found checksum for %s in database and it matched\n",filename);
- dbp->close(dbp,0);
- return false;
- }
- else
- {
- /* Key was not found, so install it */
-
- cfMDFile(filename,dbdigest);
- digest[16] = '\0';
-
- key.data = filename;
- key.size = strlen(filename)+1;
- value.data = (void *) dbdigest;
- value.size = 17;
-
- Debug("cfd: storing checksum for %s in database %s\n",filename,cfMDPrint(dbdigest));
-
- if ((errno = dbp->put(dbp,NULL,&key,&value,0)) != 0)
- {
- CfLog(cferror,"put failed","db->put");
- }
-
- dbp->close(dbp,0);
-
- if (ISCFENGINE)
- {
- return false; /* No need to warn when first installed */
- }
- else
- {
- return true;
- }
- }
-
- #else
- Verbose("cfd: No Berkeley DB2 database support available.\n");
- return false;
- #endif
- }
-
- /*************************************************************************/
-
- IgnoredOrExcluded(action,file,inclusions,exclusions)
-
- enum actions action;
- char *file;
- struct Item *inclusions, *exclusions;
-
- { char linkbuf[bufsize], *lastnode;
-
- Debug("IgnoredOrExcluded(%s)\n",file);
-
- if (strstr(file,"/"))
- {
- for (lastnode = file+strlen(file); *lastnode != '/'; lastnode--)
- {
- }
-
- lastnode++;
- }
- else
- {
- lastnode = file;
- }
-
- if (inclusions != NULL && !IsWildItemIn(inclusions,lastnode))
- {
- Debug("cfengine: skipping non-included pattern %s\n",file);
- return true;
- }
-
- switch(action)
- {
- case image:
- if (IsWildItemIn(VEXCLUDECOPY,lastnode) || IsWildItemIn(exclusions,lastnode))
- {
- sprintf(OUTPUT,"Skipping excluded pattern %s\n",file);
- CfLog(cfverbose,OUTPUT,"");
- return true;
- }
- case links:
- if (IsWildItemIn(VEXCLUDELINK,lastnode) || IsWildItemIn(exclusions,lastnode))
- {
- sprintf(OUTPUT,"kipping excluded pattern %s\n",file);
- CfLog(cfverbose,OUTPUT,"");
- return true;
- }
- default:
- if (IsWildItemIn(exclusions,lastnode))
- {
- sprintf(OUTPUT,"Skipping excluded pattern %s\n",file);
- CfLog(cfverbose,OUTPUT,"");
- return true;
- }
- }
-
- return false;
- }
-
-
- /*********************************************************************/
-
- Banner(string)
-
- char *string;
-
- {
- Verbose("---------------------------------------------------------------------\n");
- Verbose("%s\n",string);
- Verbose("---------------------------------------------------------------------\n\n");
- }
-
-
- /*********************************************************************/
-
- SetDomainName(sp) /* Bas van der Vlies */
-
- char *sp;
-
- { char fqn[maxvarsize];
- char *ptr;
- char buffer[bufsize];
-
- if (gethostname(fqn, sizeof(fqn)) != -1)
- {
- strcpy(VFQNAME,fqn);
- strcpy(buffer,VFQNAME);
- AddClassToHeap(CanonifyName(buffer));
- AddClassToHeap(CanonifyName(ToLowerStr(buffer)));
-
- if (strstr(fqn,"."))
- {
- ptr = strchr(fqn, '.');
- strcpy(VDOMAIN, ++ptr);
- }
- }
-
- if (strstr(VFQNAME,".") == 0)
- {
- strcat(VFQNAME,".");
- strcat(VFQNAME,VDOMAIN);
- }
-
- AddClassToHeap(CanonifyName(VDOMAIN));
- }
-